home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ov143b.zip
/
DIRECT.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-01-04
|
21KB
|
710 lines
PAGE 60,132
TITLE Routines to do direct screen I/O
; 012 18-Apr-87 direct.asm
; Copyright (c) 1986,1987 by Blue Sky Software. All rights reserved.
;****************************************************************************
;****** Make sure the following symbol matches calling program usage ********
;****************************************************************************
ALTCALL EQU 'pascal' ; Uses alternate calling sequence when defined
;****************************************************************************
B_proc MACRO lname,uname ; simple Begin proc macro
IFDEF ALTCALL
PUBLIC uname
uname PROC NEAR
ELSE
PUBLIC lname
lname PROC NEAR
ENDIF
ENDM
E_proc MACRO lname,uname,n ; simple End proc macro
IFDEF ALTCALL
ret n
uname ENDP
ELSE
ret
lname ENDP
ENDIF
ENDM
Param MACRO sym,cway,pway ; simple parameter defination macro
IFDEF ALTCALL
sym EQU [bp+pway]
ELSE
sym EQU [bp+cway]
ENDIF
ENDM
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
CONST SEGMENT WORD PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
DGROUP GROUP CONST, _BSS, _DATA
ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
_DATA SEGMENT
EXTRN _screen:DWORD
EXTRN _cursor:DWORD
EXTRN _vid_attrib:BYTE
EXTRN _vid_snow:BYTE
boxloc dw 0 ; stores the starting offset to the dialog box
_DATA ENDS
_TEXT SEGMENT
;******************************************************************************
;
; gotorc(row,col) move 'cursor' to specified row, col
;
;******************************************************************************
B_proc _gotorc,GOTORC
Param Row,4,6
Param Col,6,4
push bp
mov bp,sp
mov ax,Row ; row to ax
mov cl,5
shl ax,cl ; row * 32
mov bx,ax
shl ax,1
shl ax,1 ; row * 128
add ax,bx ; row * 160
mov bx,Col ; col to bx
shl bx,1 ; col * 2
add ax,bx ; row * 160 + col * 2 = cursor
mov WORD PTR _cursor,ax
mov sp,bp
pop bp
E_proc _gotorc,GOTORC,4
;******************************************************************************
;
; disp_str(s) display a string at current location
;
;******************************************************************************
B_proc _disp_str,DISP_STR
push bp
mov bp,sp
push di
push si
mov si,[bp+4]
mov ah,_vid_attrib ; attribute byte to ah
les di,DWORD PTR _cursor ; cursor ptr to es:di
jmp SHORT tst_ch ; skip to load/test code
chloop:
IFDEF nosnow ; if adapter doesn't snow, its quick
stosw ; store char and attrib to es:[di++]
ELSE ; well, its not so quick or easy....
mov cx,1
call stvideo
ENDIF
tst_ch: lodsb ; string char to al
or al,al ; done when char = 0
jne chloop
mov WORD PTR _cursor,di ; update cursor offset
pop si
pop di
mov sp,bp
pop bp
E_proc _disp_str,DISP_STR,2
;******************************************************************************
;
; disp_char(ch) display a single char at current location
;
;******************************************************************************
B_proc _disp_char,DISP_CHAR
push bp
mov bp,sp
push di
les di,DWORD PTR _cursor ; cursor loc to es:di
mov al,[bp+4] ; get char to store in video memory
mov ah,_vid_attrib ; get video attribute
IFDEF nosnow
stosw ; store 'em and update di
ELSE
mov cx,1
call stvideo
ENDIF
mov WORD PTR _cursor,di ; update cursor offset
pop di
mov sp,bp
pop bp
E_proc _disp_char,DISP_CHAR,2
;******************************************************************************
;
; disp_rep(ch,cnt) display a single char cnt times at current location
;
;******************************************************************************
B_proc _disp_rep,DISP_REP
Param Ch_d,4,6
Param Cnt,6,4
push bp
mov bp,sp
push di
les di,DWORD PTR _cursor ; cursor loc to es:di
mov al,Ch_d ; get char to store in video memory
mov ah,_vid_attrib ; get video attribute
mov cx,Cnt ; rep count to cx
IFDEF nosnow
rep stosw ; store 'em and update di
ELSE
call stvideo
ENDIF
mov WORD PTR _cursor,di ; update cursor offset
pop di
mov sp,bp
pop bp
E_proc _disp_rep,DISP_REP,4
;******************************************************************************
;
; insert_line(row,n) insert a line at row, effects n lines
;
;******************************************************************************
Param Row_l,4,6 ; Parameters for insert_line, delete_line,
Param Num_l,6,4 ; scroll_video
B_proc _insert_line,INSERT_LINE
push bp
mov bp,sp
push di
push si
mov bx,Row_l ; ( r + n - 1) * 160 - 2 =
add bx,Num_l ; end of new last row
dec bx
mov ax,160
imul bx
dec ax
dec ax
mov si,ax ; (but its the source for the move)
add ax,160 ; call addr of dest (where new last
mov di,ax ; line will go)
std ; to insert a row, need to go backwards
call scroll_video ; scroll the video buffer
mov al,20h ; fill the inserted line with blanks
mov ah,_vid_attrib
mov cx,80
IFDEF nosnow
rep stosw
ELSE
call stvideo
ENDIF
cld ; C expects it this way
pop si
pop di
mov sp,bp
pop bp
E_proc _insert_line,INSERT_LINE,4
;******************************************************************************
;
; delete_line(r,n) delete a line at row, effects n lines
;
;******************************************************************************
B_proc _delete_line,DELETE_LINE
push bp
mov bp,sp
push di
push si
mov ax,160 ; get row
imul WORD PTR Row_l ; turn into offset in video ram
mov di,ax
add ax,160 ; calc offset of next row
mov si,ax
call scroll_video ; scroll the video buffer
mov al,20h ; fill the last line with blanks
mov ah,_vid_attrib
mov cx,80
IFDEF nosnow
rep stosw
ELSE
call stvideo
ENDIF
pop si
pop di
mov sp,bp
pop bp
E_proc _delete_line,DELETE_LINE,4
;*****************************************************************************
;
; scroll_video support routine for insert/delete line
;
;*****************************************************************************
scroll_video PROC NEAR
mov ax,80 ; get # rows to move and
imul WORD PTR Num_l ; turn into # words to move
mov cx,ax
IFNDEF nosnow
mov al,_vid_snow ; movideo needs vid_snow - get it
ENDIF ; before ds gets changed
push ds ; save current ds
mov bx,WORD PTR _screen+2 ; segment address of video ram
mov ds,bx ; moving to/from video ram
mov es,bx
IFDEF nosnow
rep movsw ; scroll the data in the video buffer
ELSE
call movideo
ENDIF
pop ds ; restore ds
ret
scroll_video ENDP
;******************************************************************************
;
; scrcpy(to,from)
; char far *to, far *from;
;
; copy screen image from to
;
;******************************************************************************
B_proc _scrcpy,SCRCPY
Param To,4,8
Param From,8,4
push bp
mov bp,sp
push di
push si
push ds
IFNDEF nosnow
mov al,_vid_snow ; flag for movideo
ENDIF
les di,To ; es:di is to address
lds si,From ; ds:si is from address
mov cx,80*25 ; HARDCODED screen size in words
IFDEF nosnow ; move the screen image
rep movsw
ELSE
call movideo
ENDIF
pop ds
pop si
pop di
mov sp,bp
pop bp
E_proc _scrcpy,SCRCPY,8
;******************************************************************************
;
; popup(row,col,nrows,ncols,savp)
;
; pop up a dialog box on the screen starting at row,col.
; If savp is not NULL, the current contents of the video ram
; under the box are saved.
;
;******************************************************************************
Param Row_p,4,12 ; parameters for popup() & popdwn()
Param Col_p,6,10
Param Nrows,8,8
Param Ncols,10,6
Param Savp,12,4
B_proc _popup,POPUP
push bp
mov bp,sp
push di
push si
mov ax,160 ; calc offset to start of
imul WORD PTR Row_p ; dialog box -
mov cx,Col_p ; row * 160 + (col << 1)
shl cx,1
add ax,cx
mov si,ax ; si now -> box start offset
mov boxloc,si ; save it for later
mov di,Savp ; get savp, the save addr ptr
or di,di ; does user want contents saved?
je skipsave
mov dx,si ; save current row offset
mov bh, BYTE PTR Nrows ; nrows to bh
mov bl, BYTE PTR Ncols ; ncols to bl
mov ax,ds ; set es and ds so str instrs
mov es,ax ; work the way we want
mov cx,WORD PTR _screen+2 ; ds points to video ram
mov ds, cx
IFNDEF nosnow
mov al,es: _vid_snow ; movideo needs _vid_snow
push ax
ENDIF
nxtrow: mov cl,bl ; move ncols to cx
xor ch,ch
IFDEF nosnow
rep movsw ; move data
ELSE
pop ax ; get/save _vid_snow
push ax
call movideo
ENDIF
add dx,160 ; calc offset of next row
mov si,dx
dec bh ; one more row done, any more?
jnz nxtrow
IFNDEF nosnow
pop ax ; clear stack
ENDIF
mov ax,es ; restore the ds reg
mov ds,ax
mov si,boxloc ; reget box starting offset
skipsave:
mov di,si ; video ram is now the dest
mov es,WORD PTR _screen+2 ; video ram segment
mov al,201 ; disp the upper left corner
mov ah,_vid_attrib ; the video attrib to use
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
mov cx,Ncols ; now do the horizontal line
dec cx ; its ncols - 2 long
dec cx
mov Ncols,cx ; ncols - 2 is used again
mov al,205 ; horizontal bar char
IFDEF nosnow
rep stosw
ELSE
call stvideo
ENDIF
mov al,187 ; disp the upper right corner
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
; now do the blank lines in the body of the box
mov bx,Nrows ; the body is nrows - 2 long
dec bx
dec bx
add si,160 ; bump row offset
mov di,si
rownxt: mov al,186 ; do the left vertical bar
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
mov cx,Ncols ; now all the blanks
mov al,32
IFDEF nosnow
rep stosw
ELSE
call stvideo
ENDIF
mov al,186 ; do the right vertical bar
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
add si,160 ; bump row offset
mov di,si
dec bx ; another row done
jnz rownxt
; now do the bottom row of the box
mov al,200 ; disp the lower left corner
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
mov cx,Ncols ; now do the horizontal line
mov al,205 ; horizontal bar char
IFDEF nosnow
rep stosw
ELSE
call stvideo
ENDIF
mov al,188 ; disp the lower right corner
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
pop si ; done, exit
pop di
mov sp,bp
pop bp
E_proc _popup,POPUP,10
;******************************************************************************
;
; popdwn(row,col,nrows,ncols,savp)
;
; Remove a pop up dialog box from the screen by restoring the prior
; contents from savp.
;
;******************************************************************************
B_proc _popdwn,POPDWN
push bp
mov bp,sp
push di
push si
mov ax,160 ; calc offset to start of
imul WORD PTR Row_p ; dialog box -
mov cx,Col_p ; row * 160 + (col << 1)
shl cx,1
add ax,cx
mov di,ax ; di now -> box start offset
mov si,Savp ; get savp, the save addr ptr
mov dx,di ; save current row offset
mov bh, BYTE PTR Nrows ; nrows to bh
mov bl, BYTE PTR Ncols ; ncols to bl
mov es,WORD PTR _screen+2 ; oh yea, es points to video ram
next: mov cl,bl ; move ncols to cx
xor ch,ch
IFDEF nosnow
rep movsw ; move data
ELSE
mov al,_vid_snow
call movideo
ENDIF
add dx,160 ; calc offset of next row
mov di,dx
dec bh ; one more row done, any more?
jnz next
pop si
pop di
mov sp,bp
pop bp
E_proc _popdwn,POPDWN,10
IFNDEF nosnow
;******************************************************************************
;
; movideo - move data to/from video memory
; - current video mode must be passed in al
;
;******************************************************************************
movideo PROC NEAR
test al,1 ; do we need to check for snow?
jnz goslow
rep movsw ; no snow, full speed ahead
ret ; that's all there is to it
goslow: push dx ; it's a cga, go slow time
mov dx,03dah ; dx = cga status port address
wait1: in al,dx ; get retrace status
test al,8 ; vertical retrace?
jnz mov_it ; yes, go get the char
ror al,1 ; low bit set? (horizontal retrace)
jc wait1 ; current retrace may be almost done
cli ; no interrupts until char loaded
wait2: in al,dx ; wait for start of next retrace
ror al,1
jnc wait2
mov_it: movsw ; move word to/from video ram
sti ; allow interrupts
loop wait1 ; all chars transfered?
pop dx ; restore dx
ret
movideo ENDP
;******************************************************************************
;
; stvideo - store the word in ax to video ram cx times
;
;******************************************************************************
stvideo PROC NEAR
test _vid_snow,1 ; do we need to slow for no snow?
jnz slowgo
rep stosw ; no snow, full speed ahead
ret ; that's all there is to it
slowgo: push bx ; snow, go slow
push dx
mov dx,03dah ; dx = cga status port address
mov bx,ax
wait3: in al,dx ; get retrace status
test al,8 ; vertical retrace?
jnz sto_it ; yes, go get the char
ror al,1 ; low bit set? (horizontal retrace)
jc wait3 ; current retrace may be almost done
cli ; no interrupts until char loaded
wait4: in al,dx ; wait for start of next retrace
ror al,1
jnc wait4
sto_it: mov ax,bx
stosw ; store word to video ram
sti ; allow interrupts
loop wait3 ; all chars transfered?
pop dx ; restore dx & bx
pop bx
ret
stvideo ENDP
ENDIF
_TEXT ENDS
END